/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package hearts;

import java.security.SecureRandom;
import java.util.ArrayList;

/**
 *
 * @author TAI
 */
public class gameEngine implements Runnable{
	private int currentStep;
	private int currentTurn;//Nguoi choi hien tai
        private int firstTurn;//Nguoi choi dau tien
        private int roundCount;//So luot da choi
	private human player1;
	private computer com1,com2,com3;
	private computer[] com;
	private giaoDien gdien;

	private ArrayList<card> bonCard;
	private ArrayList<Integer> baCard;
	private boolean haiChuonDaDuocChoi,duocChonCo;
	private int[] SignalFlag; //0:card 12:control

	private int delay=500;
	public gameEngine(String st){
		player1=new human();
		player1.setTen(st);
		com1=new computer();
		com2=new computer();
		com3=new computer();
		com=new computer[]{com1,com2,com3};
		SignalFlag=new int[2];
		SignalFlag[0]=-1;
		SignalFlag[1]=0;
		bonCard=new ArrayList<card>();
		baCard=new ArrayList<Integer>();
		gdien=new giaoDien(this);
		Thread xuly=new Thread(this);
		xuly.start();
	}

	public player getPlayer(int index) {
		switch (index) {
		case 1:return player1;
		case 2: case 3: case 4: return com[index-2];
		default: return null;
		}
	}
	public ArrayList<card> getBonCard(){
		return bonCard;
	}
	public void updateDelay(int time) {
		delay=time;
	}
	public int[] getSignal() {
		return SignalFlag;
	}
	public void chiaCard(){
		int[] ddau=new int[53];
		for (int i=1;i<53;i++)
			ddau[i]=0;
		SecureRandom numGenerate=new SecureRandom();
		int tam=numGenerate.nextInt(53);
		for (int i=1;i<53;i++)
		{
			while ((tam==0)||(ddau[tam]==1)){
				tam=numGenerate.nextInt(53);
			}
			ddau[tam]=1;
			card c=new card(tam);
			switch (i%4) {
				case 1:
					player1.nhanCard(c);
					gdien.drawAllCard();
					try {
						Thread.sleep(delay/10);
					}
					catch (Exception e) {
					}
					break;
				case 2:
					com1.nhanCard(c);
					gdien.drawAllCard();
					try {
						Thread.sleep(delay/10);
					}
					catch (Exception e) {
					}
					break;
				case 3:
					com2.nhanCard(c);
					gdien.drawAllCard();
					try {
						Thread.sleep(delay/10);
					}
					catch (Exception e) {
					}
					break;
				case 0:
					com3.nhanCard(c);
					gdien.drawAllCard();
					try {
						Thread.sleep(delay/10);
					}
					catch (Exception e) {
					}
			}
		}
	}

	public void notice(String st){
		gdien.notice(st);
	}


	public card check4CardWin(){
		card max=bonCard.get(0);
		for (int i=1;i<=3;i++){
			if (bonCard.get(i).lonHon(max)) max=bonCard.get(i);
		}
		return max;
	}


	public void shootTheMoon(){
		if (player1.kiemTraShootTheMoon()){
			com1.addScore(26);
			com2.addScore(26);
			com3.addScore(26);
		}
		else
			for (int i=0;i<=2;i++){
				if (com[i].kiemTraShootTheMoon()){
					player1.addScore(26);
					for (int j=0;j<=2;j++)
						if (j!=i) com[j].addScore(26);
				}
			}
	}

	public boolean check100Score(){
		if (player1.getScore()>=100)
			return true;
		else{
			for (int i=0;i<=2;i++)
				if (com[i].getScore()>=100) return true;
			return false;
		}
	}

	public int getMinScore(){
		int min=player1.getScore();
		int winplayer=1;
		for (int i=0;i<=2;i++)
			if (com[i].getScore()<min){
				min=com[i].getScore();
				winplayer=i+2;
			}
		return winplayer;
	}

	public void processEndRound(){
		shootTheMoon();
		currentStep=3;
		gdien.notice("Player1: "+player1.getScore()+"   Comuter1: "+com1.getScore()+
				"   Computer2: "+com2.getScore()+"  Computer3:  "+com3.getScore());
		if (check100Score()==false){
			gdien.showbutton("New Round");
			gdien.drawAllCard();
		}
		else
		{
			gdien.showbutton("New Game");
			if (getMinScore()==1)
				gdien.notice("You WIN !!!");
			else
				gdien.notice("You LOSE !!!");
			//player1.resetScore();
			//com1.resetScore();
			//com2.resetScore();
			//com3.resetScore();
                        SignalFlag[1] = 1;
		}

	}

	public void checkEnd4Card(){
		if (bonCard.size()==4){
			card winCard=check4CardWin();
			if (player1.kiemTraDaChuaCard(winCard.getID())){
				player1.add4ScoreCard(bonCard);
				firstTurn=1;
				currentTurn=firstTurn;
			}
			else{
				for (int i=0;i<=2;i++){
					if (com[i].kiemTraDaChuaCard(winCard.getID())){
						com[i].add4ScoreCard(bonCard);
						firstTurn=i+2;
						currentTurn=firstTurn;
						break;
					}
				}
			}
			gdien.drawAllCard();
			try {
				Thread.sleep(delay);
			}
			catch (Exception e) {
			}
			roundCount++;
			if (roundCount==13){
				processEndRound();
			}
		}
	}

        //Chuyen
	public void nextTurn(){
		currentTurn=currentTurn==4?1:currentTurn+1;
	}

	public void getFirstTurn(){
		if (player1.kiemTraDaChuaCard(2))
			firstTurn=1;
		else
			for (int i=0;i<=2;i++)
				if (com[i].kiemTraDaChuaCard(2)){
					firstTurn=i+2;
					break;
				}
	}

	public void computerPlay(){
		while ((currentTurn!=1)&&(currentStep==2)){
			if (currentTurn==firstTurn){
				bonCard.add(com[currentTurn-2].choiDauTien(duocChonCo));
			}
			else{
				bonCard.add(com[currentTurn-2].choiSau(bonCard.get(0)));
				if ((bonCard.get(bonCard.size()-1)).kiemTraChatCo()) duocChonCo=true;
			}
			gdien.drawAllCard();
			try {
				Thread.sleep(delay);
			}
			catch (Exception e) {
			}
			nextTurn();
			checkEnd4Card();
		}
	}

	public void receiveClick(int cardClicked) {
		if (currentStep==1){ //step1: hoan doi bai
			if (cardClicked!=0){ //click vao 1 la bai
				if (baCard.contains(cardClicked)){
					for (int i=0;i<baCard.size();i++)
						if (baCard.get(i)==cardClicked){
							baCard.remove(i);
							break;
						}
					gdien.setnomal(cardClicked);
				}
				else{
					if (baCard.size()!=3){
						baCard.add(cardClicked);
						gdien.sethightlight(cardClicked);
					}
				}
			}
			else{ //click vao button
				if (baCard.size()==3){//doi 3 la bai
					card card1,card2;
					for (int i=0;i<=2;i++){
						card1=player1.passLeftMotCard(baCard.get(i));
						card2=com[i].passLeftMotRandomCard();
						player1.nhanCard(baCard.get(i), card2);
						com[i].nhanCard(card1);
					}
					baCard.clear();
					gdien.hideButton();
					currentStep=2;
					player1.sapXepCardTrongDanhSach();
					for (int i=0;i<=2;i++){
						com[i].sapXepCardTrongDanhSach();
					}

					//init cho step 2
					getFirstTurn();
					currentTurn=firstTurn;
					if (currentTurn!=1){
						bonCard.add(com[currentTurn-2].choi2Chuon());
						gdien.drawAllCard();
						try {
							Thread.sleep(delay);
						}
						catch (Exception e) {
						}
						haiChuonDaDuocChoi=true;
						nextTurn();
					}
					computerPlay();
					gdien.drawAllCard();
				}
				else
					gdien.notice("Ban phai chon du 3 la bai !!!");
			}
		}
		else{
			if (currentStep==2){//step 2:play
				if (!haiChuonDaDuocChoi){//human di 2 chuon truoc
					if (player1.layCardTrongDanhSach(cardClicked).getID()==2){
						bonCard.add(player1.choiMotCard(cardClicked));

						gdien.drawAllCard();
						try {
						Thread.sleep(delay);
						}
						catch (Exception e) {
						}
						haiChuonDaDuocChoi=true;
						nextTurn();
					}
					else
						gdien.notice("Ban phai di 2 chuon truoc");
				}
				else{
					if(bonCard.isEmpty()){//trong 1 luot human di dau tien
						if ((player1.layCardTrongDanhSach(cardClicked).kiemTraChatCo())&&(!duocChonCo)){
							gdien.notice("Chua co la Co nao ra");
						}
						else{
							if (player1.layCardTrongDanhSach(cardClicked).getID()==41)
								gdien.notice("Ban khong duoc di dam bich");
							else{
								bonCard.add(player1.choiMotCard(cardClicked));
								gdien.drawAllCard();
								try {
								Thread.sleep(delay);
								}
								catch (Exception e) {
								}
								nextTurn();
							}
						}
					}
					else{//human di theo
                                                /*
                                                 Trong 1 luot choi kiem tra
                                                 -Human lay Card co cung chat voi Card dau tien duoc dua ra
                                                 -Hoac trong danh sach Card cua Human khong ton tai chat Card dau tien duoc dua ra 
                                                 */

						if ((player1.layCardTrongDanhSach(cardClicked).kiemTraCungChat(bonCard.get(0)))||
							(!player1.kiemTraChatCardChuaChoi(bonCard.get(0)))){
							bonCard.add(player1.choiMotCard(cardClicked));
							if (player1.layCardTrongDanhSach(cardClicked).kiemTraChatCo()) duocChonCo=true;
							gdien.drawAllCard();
							try {
								Thread.sleep(delay);
							}
							catch (Exception e) {
							}
							nextTurn();
							checkEnd4Card();
						}
						else
							gdien.notice("Ban phai di cung nuoc voi la dau tien");
					}
				}
				computerPlay();
			}
			else{//step 3
				newRound();
			}
		}
	}

	public void run() {
		while (true) {
			if (SignalFlag[0]!=-1) {
				receiveClick(SignalFlag[0]);
				SignalFlag[0]=-1;
			}
			if (SignalFlag[1]!=0) {
				newGame();
				SignalFlag[1]=0;
			}
			try {
				Thread.sleep(100);
			}
			catch (Exception e) {
			}
		}
	}

	public void newRound(){
		player1.newRound();
		for (int i=0;i<=2;i++){
			com[i].newRound();
		}
		chiaCard();
		player1.sapXepCardTrongDanhSach();
		for (int i=0;i<=2;i++){
			com[i].sapXepCardTrongDanhSach();
		}
		haiChuonDaDuocChoi=false;
		duocChonCo=false;
		currentStep=1;
		roundCount=0;
		gdien.showbutton("Pass Left");
		gdien.drawAllCard();
	}

	public void newGame() {
		player1.resetScore();
		com1.resetScore();
		com2.resetScore();
		com3.resetScore();
		bonCard.clear();
		newRound();
	}
	public static void main(String[] args){
		gameEngine gameE=new gameEngine("TAI");
		gameE.newRound();
	}


}
